﻿namespace QMVnSoft.Controls.ChildGridControls
{
    using QMVnSoft;
    using System;
    using System.ComponentModel;
    using System.Windows.Forms;

    public class NumericColumn : DataGridViewColumn
    {
        public NumericColumn()
        {
            NumericCell cell = new NumericCell();
            this.CellTemplate = cell;
            this.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            base.SortMode = DataGridViewColumnSortMode.Automatic;
        }

        private void SetNumericFormat()
        {
            if (AppInstance.NumberDigits != 0)
            {
                switch (this.NumericCellTemplate.UserTextNumericFormat)
                {
                    case AppInstance.TextNumericFormat.None:
                        return;

                    case AppInstance.TextNumericFormat.Quantity:
                        this.NumericPrecision = AppInstance.NumberDigits + AppInstance.QuantityDecimals;
                        this.NumericScaleOnFocus = AppInstance.QuantityDecimals;
                        this.NumericScaleOnLostFocus = AppInstance.QuantityDecimals;
                        return;

                    case AppInstance.TextNumericFormat.NormQuantity:
                        this.NumericPrecision = AppInstance.NumberDigits + AppInstance.NormQuantity;
                        this.NumericScaleOnFocus = AppInstance.NormQuantity;
                        this.NumericScaleOnLostFocus = AppInstance.NormQuantity;
                        return;

                    case AppInstance.TextNumericFormat.RatioQuantity:
                        this.NumericPrecision = AppInstance.NumberDigits + AppInstance.RatioFormat;
                        this.NumericScaleOnFocus = AppInstance.RatioFormat;
                        this.NumericScaleOnLostFocus = AppInstance.RatioFormat;
                        return;

                    case AppInstance.TextNumericFormat.LocalPrice:
                        this.NumericPrecision = AppInstance.NumberDigits + AppInstance.LCPriceDecimals;
                        this.NumericScaleOnFocus = AppInstance.LCPriceDecimals;
                        this.NumericScaleOnLostFocus = AppInstance.LCPriceDecimals;
                        return;

                    case AppInstance.TextNumericFormat.ForeignPrice:
                        this.NumericPrecision = AppInstance.NumberDigits + AppInstance.FCPriceDecimals;
                        this.NumericScaleOnFocus = AppInstance.FCPriceDecimals;
                        this.NumericScaleOnLostFocus = AppInstance.FCPriceDecimals;
                        return;

                    case AppInstance.TextNumericFormat.LocalAmount:
                        this.NumericPrecision = AppInstance.NumberDigits + AppInstance.LCAmountDecimals;
                        this.NumericScaleOnFocus = AppInstance.LCAmountDecimals;
                        this.NumericScaleOnLostFocus = AppInstance.LCAmountDecimals;
                        return;

                    case AppInstance.TextNumericFormat.ForeignAmount:
                        this.NumericPrecision = AppInstance.NumberDigits + AppInstance.FCAmountDecimals;
                        this.NumericScaleOnFocus = AppInstance.FCAmountDecimals;
                        this.NumericScaleOnLostFocus = AppInstance.FCAmountDecimals;
                        return;

                    case AppInstance.TextNumericFormat.Percent:
                        this.NumericPrecision = AppInstance.NumberDigits + AppInstance.PercentDecimals;
                        this.NumericScaleOnFocus = AppInstance.PercentDecimals;
                        this.NumericScaleOnLostFocus = AppInstance.PercentDecimals;
                        return;

                    case AppInstance.TextNumericFormat.ExchangeRate:
                        this.NumericPrecision = AppInstance.NumberDigits + AppInstance.ExchangeFormat;
                        this.NumericScaleOnFocus = AppInstance.ExchangeFormat;
                        this.NumericScaleOnLostFocus = AppInstance.ExchangeFormat;
                        return;

                    case AppInstance.TextNumericFormat.IntNumber:
                        this.NumericPrecision = AppInstance.NumberDigits;
                        this.NumericScaleOnFocus = 0;
                        this.NumericScaleOnLostFocus = 0;
                        return;
                }
            }
        }

        [DefaultValue(true), Description("Indicates if the value found valid."), RefreshProperties(RefreshProperties.All), Category("Numeric column properties")]
        public bool AllowNegative
        {
            get
            {
                if (this.NumericCellTemplate == null)
                {
                    throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
                }
                return this.NumericCellTemplate.AllowNegative;
            }
            set
            {
                if (this.NumericCellTemplate == null)
                {
                    throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
                }
                this.NumericCellTemplate.AllowNegative = value;
                if (base.DataGridView != null)
                {
                    DataGridViewRowCollection rows = base.DataGridView.Rows;
                    int count = rows.Count;
                    for (int i = 0; i < count; i++)
                    {
                        NumericCell cell = rows.SharedRow(i).Cells[base.Index] as NumericCell;
                        if (cell != null)
                        {
                            cell.SetAllowNegative(i, value);
                        }
                    }
                    base.DataGridView.InvalidateColumn(base.Index);
                }
            }
        }

        public override DataGridViewCell CellTemplate
        {
            get
            {
                return base.CellTemplate;
            }
            set
            {
                NumericCell cell = value as NumericCell;
                if ((value != null) && (cell == null))
                {
                    throw new InvalidCastException("Value provided for CellTemplate must be of type DataGridViewNumericUpDownElements.DataGridViewNumericUpDownCell or derive from it.");
                }
                base.CellTemplate = value;
            }
        }

        private NumericCell NumericCellTemplate
        {
            get
            {
                return (NumericCell) base.CellTemplate;
            }
            set
            {
                if ((value != null) && !value.GetType().IsAssignableFrom(typeof(NumericCell)))
                {
                    throw new InvalidCastException("Must be a CustomDataGridViewNumericTextBoxCell");
                }
                base.CellTemplate = value;
            }
        }

        [Description("Get or set number of digits."), DefaultValue(1), Category("Numeric column properties"), RefreshProperties(RefreshProperties.All)]
        public int NumericPrecision
        {
            get
            {
                if (this.NumericCellTemplate == null)
                {
                    throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
                }
                return this.NumericCellTemplate.NumericPrecision;
            }
            set
            {
                if (this.NumericCellTemplate == null)
                {
                    throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
                }
                this.NumericCellTemplate.NumericPrecision = value;
                if (base.DataGridView != null)
                {
                    DataGridViewRowCollection rows = base.DataGridView.Rows;
                    int count = rows.Count;
                    for (int i = 0; i < count; i++)
                    {
                        NumericCell cell = rows.SharedRow(i).Cells[base.Index] as NumericCell;
                        if (cell != null)
                        {
                            cell.SetNumericPrecision(i, value);
                        }
                    }
                    base.DataGridView.InvalidateColumn(base.Index);
                }
            }
        }

        [RefreshProperties(RefreshProperties.All), DefaultValue(0), Category("Numeric column properties"), Description("Get or set number of digits after decimal symbol when set focus.")]
        public int NumericScaleOnFocus
        {
            get
            {
                if (this.NumericCellTemplate == null)
                {
                    throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
                }
                return this.NumericCellTemplate.NumericScaleOnFocus;
            }
            set
            {
                if (this.NumericCellTemplate == null)
                {
                    throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
                }
                this.NumericCellTemplate.NumericScaleOnFocus = value;
                if (base.DataGridView != null)
                {
                    DataGridViewRowCollection rows = base.DataGridView.Rows;
                    int count = rows.Count;
                    for (int i = 0; i < count; i++)
                    {
                        NumericCell cell = rows.SharedRow(i).Cells[base.Index] as NumericCell;
                        if (cell != null)
                        {
                            cell.SetNumericScaleOnFocus(i, value);
                        }
                    }
                    base.DataGridView.InvalidateColumn(base.Index);
                }
            }
        }

        [Description("Get or set number of digits after decimal symbol when lost focus."), Category("Numeric column properties"), DefaultValue(0), RefreshProperties(RefreshProperties.All)]
        public int NumericScaleOnLostFocus
        {
            get
            {
                if (this.NumericCellTemplate == null)
                {
                    throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
                }
                return this.NumericCellTemplate.NumericScaleOnLostFocus;
            }
            set
            {
                if (this.NumericCellTemplate == null)
                {
                    throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
                }
                this.NumericCellTemplate.NumericScaleOnLostFocus = value;
                if (base.DataGridView != null)
                {
                    DataGridViewRowCollection rows = base.DataGridView.Rows;
                    int count = rows.Count;
                    for (int i = 0; i < count; i++)
                    {
                        NumericCell cell = rows.SharedRow(i).Cells[base.Index] as NumericCell;
                        if (cell != null)
                        {
                            cell.SetNumericScaleOnLostFocus(i, value);
                        }
                    }
                    base.DataGridView.InvalidateColumn(base.Index);
                }
            }
        }

        [Category("Numeric column properties"), Description("Get or set numeric format."), RefreshProperties(RefreshProperties.All), DefaultValue(0)]
        public AppInstance.TextNumericFormat UserTextNumericFormat
        {
            get
            {
                NumericCell numericCellTemplate = this.NumericCellTemplate;
                return this.NumericCellTemplate.UserTextNumericFormat;
            }
            set
            {
                if (this.NumericCellTemplate == null)
                {
                    throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
                }
                this.NumericCellTemplate.UserTextNumericFormat = value;
                this.SetNumericFormat();
            }
        }

        [DefaultValue(false), RefreshProperties(RefreshProperties.All), Category("Numeric column properties"), Description("Indicates if the value empty shown.")]
        public bool ZeroIsShown
        {
            get
            {
                if (this.NumericCellTemplate == null)
                {
                    throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
                }
                return this.NumericCellTemplate.ZeroIsShown;
            }
            set
            {
                if (this.NumericCellTemplate == null)
                {
                    throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
                }
                this.NumericCellTemplate.ZeroIsShown = value;
                if (base.DataGridView != null)
                {
                    DataGridViewRowCollection rows = base.DataGridView.Rows;
                    int count = rows.Count;
                    for (int i = 0; i < count; i++)
                    {
                        NumericCell cell = rows.SharedRow(i).Cells[base.Index] as NumericCell;
                        if (cell != null)
                        {
                            cell.SetZeroIsShown(i, value);
                        }
                    }
                    base.DataGridView.InvalidateColumn(base.Index);
                }
            }
        }

        [DefaultValue(false), Description("Indicates if the value empty valid."), RefreshProperties(RefreshProperties.All), Category("Numeric column properties")]
        public bool ZeroIsValid
        {
            get
            {
                if (this.NumericCellTemplate == null)
                {
                    throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
                }
                return this.NumericCellTemplate.ZeroIsValid;
            }
            set
            {
                if (this.NumericCellTemplate == null)
                {
                    throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");
                }
                this.NumericCellTemplate.ZeroIsValid = value;
                if (base.DataGridView != null)
                {
                    DataGridViewRowCollection rows = base.DataGridView.Rows;
                    int count = rows.Count;
                    for (int i = 0; i < count; i++)
                    {
                        NumericCell cell = rows.SharedRow(i).Cells[base.Index] as NumericCell;
                        if (cell != null)
                        {
                            cell.SetZeroIsValid(i, value);
                        }
                    }
                    base.DataGridView.InvalidateColumn(base.Index);
                }
            }
        }
    }
}

